import axios, { CanceledError } from "axios";
import type {
  ChatApiConfig,
  ChatCompletionRequestMessage,
  ChatRequestConfig,
} from "../types";
import { ElMessage } from "element-plus";
export const enum ModelType {
  Chat = "deepseek-chat",
  Reasoner = "deepseek-reasoner",
}

export class AIChatService {
  // 配置定义
  private config: ChatRequestConfig = {
    model: "deepseek-chat",
    temperature: 0.7,
    max_tokens: 2000,
    stream: false,
    system_message: "你是一个友好的中文助手。",
  };
  private api_config = {
    baseURL: "",
    apiKey: "",
  };
  private abortController: AbortController | null = null;
  constructor(api_config: ChatApiConfig) {
    if (!api_config.apiKey || !api_config.baseURL)
      throw new Error("apiKey or baseURL is empty");
    this.api_config = { ...api_config };
  }
  updateModel(model: ModelType) {
    this.config.model = model;
  }
  // 普通对话请求
  async chat(messages: ChatCompletionRequestMessage[]) {
    try {
      this.abortController = new AbortController();
      const signal = this.abortController.signal;
      const response = await axios.post(
        `${this.api_config.baseURL}/chat/completions`,
        {
          model: this.config.model,
          messages: [
            { role: "system", content: this.config.system_message },
            ...messages,
          ],
          temperature: this.config.temperature,
          max_tokens: this.config.max_tokens,
        },
        {
          headers: {
            Authorization: `Bearer ${this.api_config.apiKey}`,
          },
          signal, // 添加信号
        }
      );
      return response.data.choices[0].message.content;
    } catch (error) {
      if (error instanceof CanceledError && error.name === "CanceledError") {
        console.log("请求已中止");
      } else {
        console.error(error);
        throw new Error("流式聊天服务出错了");
      }
    }
  }

  // 流式对话请求
  async streamChat(
    messages: ChatCompletionRequestMessage[],
    onChunk: (chunk: string) => void,
    onDone: () => void
  ) {
    try {
      this.abortController = new AbortController();
      const signal = this.abortController.signal;
      const response = await fetch(
        `${this.api_config.baseURL}/chat/completions`,
        {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
            Authorization: `Bearer ${this.api_config.apiKey}`,
          },
          signal,
          body: JSON.stringify({
            model: this.config.model,
            messages: [
              { role: "system", content: this.config.system_message },
              ...messages,
            ],
            stream: true,
          }),
        }
      );

      const reader = response.body?.getReader();
      const decoder = new TextDecoder();

      while (reader) {
        const { done, value } = await reader.read();
        if (done) break;

        const chunk = decoder.decode(value);
        const lines = chunk.split("\n").filter((line) => line.trim());

        for (const line of lines) {
          if (line.startsWith("data: ")) {
            const data = line.slice(6);
            if (data === "[DONE]") {
              onDone();
              break; // 流结束
            }
            try {
              const parsedData = JSON.parse(data);
              const content = parsedData.choices[0].delta.content;
              if (content) onChunk(content);
            } catch (parseError) {
              console.error("解析JSON失败:", parseError);
            }
          }
        }
      }
    } catch (error) {
      if (error instanceof CanceledError && error.name === "CanceledError") {
        console.log("请求已中止");
      } else {
        console.error(error);
        throw new Error("流式聊天服务出错了");
      }
    }
  }
  // 新增方法用于中止请求
  abortStreamChat() {
    if (this.abortController) {
      this.abortController.abort();
      this.abortController = null;
    }
  }
}

let aiServiceClint: AIChatService;
export const getAiService = ({
  apiKey,
  baseURL,
}: {
  apiKey: string;
  baseURL: string;
}) => {
  if (aiServiceClint) return aiServiceClint;
  if (!apiKey || !baseURL) {
    ElMessage.error("请先配置好apiKey和baseURL");
    return;
  }
  if (!aiServiceClint) {
    aiServiceClint = new AIChatService({
      baseURL,
      apiKey,
    });
  }
  return aiServiceClint;
};
